package com.hmsm.rtx;

import java.util.HashMap;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.hmsm.server.common.CommonUtil;
import com.hmsm.server.util.URLHelp;

public class RTXClient {
	
	private static final Log log = LogFactory.getLog(RTXClient.class);
	
	private static final String DEPT_TABLE_API = "deptTable";
	
	private static final String USER_TABLE_API = "userTable";
	
	private static final String DEPT_USER_TABLE_API = "deptUserTable";
	
	private static final String DEMO_URL_ADDRESS = "http://demo.hmsm.com.cn";
	
	private static final Map<String, RTXClient> clientMap = new HashMap<String, RTXClient>();

	public static RTXClient getInstance(String relevanceConfig) {
	
		JSONObject jsonResult = JSONObject.fromObject(relevanceConfig);
		
		String address = null;
		if (jsonResult.containsKey("address")){
			address = jsonResult.getString("address");
		}
		if (address==null||address.length()==0){
			address = getDeptTableAddress(address);
			if (address != null&&address.endsWith("/"+ DEPT_TABLE_API)&&!address.startsWith(DEMO_URL_ADDRESS)){
				address = address.substring(0,address.indexOf("/"+ DEPT_TABLE_API));
			}else{
				address = null;
			}
		}
		String rootDepartPath = null;
		if (jsonResult.containsKey("RelevanceDepartment")){
			rootDepartPath = jsonResult.getString("RelevanceDepartment");
		}
		
		RTXClient client = null;
		
		if (address!=null){
			if (clientMap.containsKey(address)){
				client = clientMap.get(address.toLowerCase());
			}
			if (client==null){
				client = new RTXClient(address, rootDepartPath);
				clientMap.put(address.toLowerCase(), client);
			}
		}
		
		return client;
	}

	private String address;
	
	private String rootDepartPath;
	
	public RTXClient(String address, String rootDepartPath){
		this.address = address;
		this.rootDepartPath = rootDepartPath;
	}

	public RTXDept getRelevanceDeptTree() throws Exception {
		return getDeptTree();
	}

	public RTXDept getRelevanceDeptTree(Integer relevanceId, String name) throws Exception {
		return getDeptTreeWithUsers(relevanceId, name, rootDepartPath);
	}
	
	public RTXDept getDeptTree() {
		RTXDept orgTreeRoot = new RTXDept();
		orgTreeRoot.setDeptName("");
		
		Map<Integer, RTXDept> rtxDepartMap = new HashMap<Integer, RTXDept>();
		rtxDepartMap.put(orgTreeRoot.getDeptId(), orgTreeRoot);
		
		String deptTableAddress = getDeptTableAddress(address); 
		if (deptTableAddress!=null&&deptTableAddress.length()>0&&!deptTableAddress.startsWith(DEMO_URL_ADDRESS)){
			try {
				mountDeptTree(orgTreeRoot, rtxDepartMap);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
		return orgTreeRoot;
	}
	
	private RTXDept getDeptTreeWithUsers(Integer relevanceId, String name, String rootDeptPath) throws Exception {
		RTXDept targetDeptTree = null;
		
		RTXDept orgTreeRoot = new RTXDept();
		orgTreeRoot.setDeptName("");
		orgTreeRoot.setDeptId(0);
		
		Map<Integer, RTXDept> rtxDepartMap = new HashMap<Integer, RTXDept>();
		rtxDepartMap.put(orgTreeRoot.getDeptId(), orgTreeRoot);
		
		mountDeptTree(orgTreeRoot, rtxDepartMap);

		mountUsers(rtxDepartMap);
		
		targetDeptTree = getRelevanceDeptTree(relevanceId, name, rootDeptPath, targetDeptTree, orgTreeRoot, rtxDepartMap);
		
		return targetDeptTree;
	}

	private void mountDeptTree(RTXDept orgTreeRoot, Map<Integer, RTXDept> rtxDepartMap) throws Exception {
		URLHelp help = new URLHelp();

		
		String deptTable = help.requestRul(getDeptTableAddress(address));// 部门JSON
		// 获取部门集合
		JSONObject deptJson = JSONObject.fromObject(deptTable);// 把部门JSON字符串转换成JSON对象
		JSONArray deptArray = deptJson.getJSONArray("deptTable");// 把部门JSON对象转换成数组

		// 循环添加部门到集合，并筛选出顶级部门列表
		for (int i = 0; i < deptArray.size(); i++) {
			JSONObject object = deptArray.getJSONObject(i);
			RTXDept rtxDepart = (RTXDept) JSONObject.toBean(object, RTXDept.class);
			rtxDepartMap.put(rtxDepart.getDeptId(), rtxDepart);
			if (rtxDepart.getPdeptId() == 0) {
				rtxDepart.setParent(orgTreeRoot);
				orgTreeRoot.getSubDepts().add(rtxDepart);
			}
		}

		// 装配部门树
		for (RTXDept deptInfo : rtxDepartMap.values()) {
			if (deptInfo.getPdeptId() > 0 && rtxDepartMap.containsKey(deptInfo.getPdeptId())) {
				RTXDept parent = rtxDepartMap.get(deptInfo.getPdeptId());
				deptInfo.setParent(parent);
				parent.getSubDepts().add(deptInfo);
			}
		}
	}

	private static String getDeptTableAddress(String address) {
		String deptTableAddress = CommonUtil.getSysConfigMap().get(DEPT_TABLE_API);
		
		if (address!=null&&address.length()>0){
			deptTableAddress = address + "/deptTable";
		}
		
		return deptTableAddress;
	}

	private String getUserTableAddress() {
		String userTableAddress = CommonUtil.getSysConfigMap().get(USER_TABLE_API);

		if (address!=null&&address.length()>0){
			userTableAddress = address + "/" + USER_TABLE_API;
		}

		return userTableAddress;
	}

	private String getDeptUserTableAddress() {
		String deptUserTableAddress = CommonUtil.getSysConfigMap().get(DEPT_USER_TABLE_API);

		if (address!=null&&address.length()>0){
			deptUserTableAddress = address + "/" + DEPT_USER_TABLE_API;
		}
		
		return deptUserTableAddress;
	}

	private RTXDept getRelevanceDeptTree(Integer relevanceId, String name, String rootDeptPath, RTXDept targetDeptTree,
			RTXDept orgTreeRoot, Map<Integer, RTXDept> rtxDepartMap) {
		// 优先使用原关联ID进行匹配
		if (relevanceId!=null&&relevanceId>0){
			Integer id = new Integer(relevanceId.intValue());
			if (rtxDepartMap.containsKey(id)){
				targetDeptTree = rtxDepartMap.get(id);
			}
		}
		// 再按部门名称进行匹配
		if (targetDeptTree==null&&name!=null&&name.length()>0){
			// 逐级按名称查找部门
			targetDeptTree = orgTreeRoot;
			if(!name.equals(targetDeptTree.getDeptName())){
				targetDeptTree = findDeptByName(name, targetDeptTree);
			}
		}
		// 再按配置中记录的部门路径进行匹配
		if (targetDeptTree==null){
			targetDeptTree = orgTreeRoot;
			if (rootDeptPath!=null&&!rootDeptPath.equals("|")){
				String[] pathNameList = rootDeptPath.split("\\|");
				for(String deptName:pathNameList){
					if (deptName!=null&&deptName.length()>0&&targetDeptTree.getSubDepts()!=null){
						targetDeptTree = findDeptByName(deptName,
								targetDeptTree);
					}
				}
			}
		}
		return targetDeptTree;
	}

	private void mountUsers(Map<Integer, RTXDept> rtxDepartMap) throws Exception {
		
		URLHelp help = new URLHelp();

		// 获取远程用户数据
		Map<Integer, RTXUser> rtxUserMap = new HashMap<Integer, RTXUser>();
		String userTable = help.requestRul(getUserTableAddress());// 用户JSON
		JSONObject userJson = JSONObject.fromObject(userTable);// 把用户JSON字符串转换成JSON对象
		JSONArray userArray = userJson.getJSONArray("userTable");// 把用户JSON对象转换成数组
		// 循环添加用户到集合
		for (int i = 0; i < userArray.size(); i++) {
			JSONObject object = userArray.getJSONObject(i);
			RTXUser rtxUser = (RTXUser) JSONObject.toBean(object, RTXUser.class);
			rtxUserMap.put(rtxUser.getId(), rtxUser);
		}

		// 装配用户部门关系
		String deptUserTable = help.requestRul(getDeptUserTableAddress());// 用户和部门关联的JSON
		JSONObject deptUserJson = JSONObject.fromObject(deptUserTable);// 把部门用户JSON字符串转换成JSON对象
		JSONArray deptUserArray = deptUserJson.getJSONArray("deptUserTable");// 把部门用户JSON对象转换成数组
		// 循环添加部门到集合
		for (int i = 0; i < deptUserArray.size(); i++) {
			RTXDeptUserBean rtxDeptUser = (RTXDeptUserBean) JSONObject.toBean(deptUserArray.getJSONObject(i), RTXDeptUserBean.class);
			log.debug("开始装配 RTX 部门和用户");
			RTXDept rtxDept = rtxDepartMap.get(rtxDeptUser.getDeptId());
			RTXUser rtxUser = rtxUserMap.get(rtxDeptUser.getUserId());
			if(rtxUser!=null&&rtxUser.getName().equals("黑马袁勇军")){
				log.debug("RTX 部门和用户装配完成");
			}
			rtxUser.setDepart(rtxDept);// 设置用户部门
			rtxDept.getUsers().add(rtxUser);
		}
		log.debug("加载 rtxDeptUsers 完毕！");
	}

	private RTXDept findDeptByName(String name, RTXDept targetDeptTree) {
		RTXDept findDept = null;
		for(Object dept:targetDeptTree.getSubDepts()){
			if (name.equals(((RTXDept) dept).getDeptName())){
				findDept = (RTXDept) dept;
				break;
			}
		}
		if (findDept==null){
			// 是否有重名
			boolean dup = false;
			for(Object subDept:targetDeptTree.getSubDepts()){
				for(Object dept:((RTXDept) subDept).getSubDepts()){
					if (name.equals(((RTXDept) dept).getDeptName())){
						if (findDept==null){
							findDept = (RTXDept) dept;
						}else{
							dup = true;
							findDept = null;
						}
						break;
					}
				}
				if (dup){
					break;
				}
			}
		}
		return findDept;
	}

}
